package com.lam.common.validate.validator;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.lam.common.utils.BeanUtil;
import com.lam.common.utils.CollectionUtil;
import com.lam.common.utils.JsonUtil;
import com.lam.common.utils.StringUtils;
import com.lam.common.utils.sql.SqlUtil;
import com.lam.common.validate.ValidateUtil;
import com.lam.common.validate.model.UniqueDesc;
import com.lam.common.validate.model.ValidOperType;

/**
 * 表字段唯一校验工具
 * @author lam
 *
 */
public class UniqueValidBean {

	/**
	 * 根据唯一配置uniqueDesc查询数据，并转换成对应的实体对象
	 * @param <T>
	 * @param object
	 * @param operType
	 * @param uniqueDesc
	 * @param clazz
	 * @return
	 */
	public static <T> T selectUniqueData(Object object, ValidOperType operType, UniqueDesc uniqueDesc, Class<T> clazz) {
		return JsonUtil.toJavaObjectWithSnake(selectUniqueData(object, ValidOperType.ADD, uniqueDesc), clazz);
	}
	
	/**
	 * 根据唯一配置uniqueDesc查询数据
	 * @param <T>
	 * @param object
	 * @param operType
	 * @param uniqueDesc
	 * @return
	 */
	public static Map<String, Object> selectUniqueData(Object object, ValidOperType operType, UniqueDesc uniqueDesc){
		
		checkParam(uniqueDesc, operType, object);
		
		String exeConditionSql = createConditionSql(uniqueDesc.getConditionSql(), uniqueDesc.getVarList(), object);
		uniqueDesc.setExeConditionSql(exeConditionSql);
		return ValidateUtil.selectData(uniqueDesc);
	}
	
	public static String checkUnique(Object object, ValidOperType operType, UniqueDesc uniqueDesc) {
		
		ValidateUtil.validRequired(object, "对象不能为空！");
		ValidateUtil.validRequired(operType, "操作类型不能为空！");
		ValidateUtil.validRequired(uniqueDesc, "唯一配置不能为空！");
		
		return ValidateUtil.validUnique(selectUniqueData(object, operType, uniqueDesc));
	}
	
	private static String createConditionSql(String conditionSql, List<String> varList, Object object) {
		if(StringUtils.isBlank(conditionSql)) {
			return "";
		}
		conditionSql = conditionSql.trim();
		conditionSql = conditionSql.toLowerCase().startsWith("and")?conditionSql:"and "+conditionSql;
		if(CollectionUtil.isEmpty(varList)) {
			return conditionSql;
		}
		
		int i =0;
		Object[] values = new Object[varList.size()];
		Object v;
		for (String var : varList) {
			if(var.trim().startsWith("$")) {
				continue;
			}
			v = BeanUtil.getValueByName(object, StringUtils.replace(var, SqlUtil.DATA_TYPE_SUFFIX_NUM, ""));
			values[i++] = v == null ? "" : v;
		}
		return SqlUtil.fillTemplate(conditionSql, varList, values);
	}
	
	private static void checkParam(UniqueDesc uniqueDesc, ValidOperType operType, Object object) {
		
		String[] columns = uniqueDesc.getUniqueField().split(",");
		Map<String, Object> uniqueFieldMap = new HashMap<>();
		uniqueDesc.setUniqueFieldMap(uniqueFieldMap);
		String field;
		Object value;
		for (String column : columns) {
			field = StringUtils.toCamelCase(column);
			value = BeanUtil.getValueByName(object, field);
			ValidateUtil.validRequired(value, field+"不能为空！");
			uniqueFieldMap.put(column, value);
		}
		
		if(ValidOperType.UPDATE == operType) {
			ValidateUtil.validRequired(uniqueDesc.getQueryField(), "不支持修改唯一校验(查询字段为空)！");
			columns = uniqueDesc.getQueryField().split(",");
			Map<String, Object> queryFieldMap = new HashMap<>();
			uniqueDesc.setQueryFieldMap(queryFieldMap);
			for (String column : columns) {
				field = StringUtils.toCamelCase(column);
				value = BeanUtil.getValueByName(object, field);
				ValidateUtil.validRequired(value, field+"不能为空！");
				queryFieldMap.put(column, value);
			}
		}
		
		if(StringUtils.isNotBlank(uniqueDesc.getConditionSql())) {
			List<String> varList = SqlUtil.getVarList(uniqueDesc.getConditionSql());
			uniqueDesc.setVarList(varList);
			for (String prop : varList) {
				if(prop.startsWith("$")) {
					continue;
				}
				if(prop.endsWith(SqlUtil.DATA_TYPE_SUFFIX_NUM)) {
					prop = prop.replace(SqlUtil.DATA_TYPE_SUFFIX_NUM, "");
				}
				ValidateUtil.validRequired(object, prop, prop+"不能为空！");
			}
		}
	}
}
